home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / Implementation / Dialogs / LnkDlgEx.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-13  |  58.2 KB  |  2,030 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        LnkDlgEx.cpp
  3.  
  4.     Contains:    implementation of the Paste As and Link Info dialogs
  5.  
  6.     Owned by:    Craig Carper
  7.  
  8.     Copyright:    © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.         <10>      10/10/96    RA        BindingUtils are now statically linked.
  13.                                     Added include
  14.          <9>     9/13/96    EL        1385235: Kind Menu should dispaly every
  15.                                     stored kind as active.
  16.          <8>     9/12/96    eeh        1386008: weak link against appleguidelib
  17.          <7>     9/11/96    eeh        1386008: AG fix for 68K
  18.          <6>     9/10/96    eeh        1386008: AppleGuide support (incomplete)
  19.          <5>      9/4/96    EL        1306385: Remove user item that are used as
  20.                                     default button in dialog.
  21.          <4>      7/8/96    eeh        undo task 10008 (AppleGuide buttons)
  22.          <3>     6/21/96    eeh        task 10008: add buttons etc. for AppleGuide
  23.          <2>     6/21/96    RA        T10025: Call InitBndNSUtils
  24.         <1>     6/7/96 eeh        first checked in (based on LinkDlgs.cpp)
  25.  
  26.     In Progress:
  27.         
  28. */
  29.  
  30. #ifndef _PLFMDEF_
  31. #include <plfmdef.h>
  32. #endif
  33.  
  34. #ifndef _LINKDLGS_
  35. #include <LinkDlgs.h>
  36. #endif
  37.  
  38. #ifndef _INFOUTIL_
  39. #include <InfoUtil.h>
  40. #endif
  41.  
  42. #ifndef _DLOGUTIL_
  43. #include <DlogUtil.h>
  44. #endif
  45.  
  46. #ifndef _EXCEPT_
  47. #include <Except.h>
  48. #endif
  49.  
  50. #ifndef _LINKDEFS_
  51. #include <LinkDefs.h>
  52. #endif
  53.  
  54. #ifndef _USERSRCM_
  55. #include <UseRsrcM.h>
  56. #endif
  57.  
  58. #ifndef _AGSUPPORT_
  59. #include "AGSupprt.h"
  60. #endif
  61.  
  62. #ifndef SOM_Module_OpenDoc_StdProps_defined
  63. #include <StdProps.xh>
  64. #endif
  65.  
  66. #ifndef SOM_Module_OpenDoc_Foci_defined
  67. #include <Foci.xh>
  68. #endif
  69.  
  70. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  71. #include <StdTypes.xh>
  72. #endif
  73.  
  74. #ifndef SOM_ODTypeList_xh
  75. #include <TypeList.xh>
  76. #endif
  77.  
  78. #ifndef SOM_ODTypeListIterator_xh
  79. #include <TypLsItr.xh>
  80. #endif
  81.  
  82. #ifndef SOM_ODStorageUnit_xh
  83. #include <StorageU.xh>
  84. #endif
  85.  
  86. #ifndef SOM_ODPart_xh
  87. #include <Part.xh>
  88. #endif
  89.  
  90. #ifndef SOM_ODFrame_xh
  91. #include <Frame.xh>
  92. #endif
  93.  
  94. #ifndef SOM_ODFacet_xh
  95. #include <Facet.xh>
  96. #endif
  97.  
  98. #ifndef SOM_ODBaseLink_xh
  99. #include <LinkB.xh>
  100. #endif
  101.  
  102. #ifndef SOM_ODBaseLinkSource_xh
  103. #include <LinkSrcB.xh>
  104. #endif
  105.  
  106. #ifndef SOM_ODBinding_xh
  107. #include <ODBindng.xh>
  108. #endif
  109.  
  110. #ifndef SOM_ODTranslation_xh
  111. #include <Translt.xh>
  112. #endif
  113.  
  114. #ifndef SOM_ODWindowState_xh
  115. #include <WinStat.xh>
  116. #endif
  117.  
  118. #ifndef _BINDNGH_
  119. #include <BindngH.h>
  120. #endif
  121.  
  122. #ifndef _BNDNSUTL_
  123. #include <BndNSUtl.h>
  124. #endif
  125.  
  126. #ifndef SOM_ODSession_xh
  127. #include <ODSessn.xh>
  128. #endif
  129.  
  130. #ifndef SOM_ODArbitrator_xh
  131. #include <Arbitrat.xh>
  132. #endif
  133.  
  134. #ifndef SOM_ODDispatcher_xh
  135. #include <Disptch.xh>
  136. #endif
  137.  
  138. #ifndef _ODUTILS_
  139. #include <ODUtils.h>
  140. #endif
  141.  
  142. #ifndef _PASCLSTR_
  143. #include <PasclStr.h>
  144. #endif
  145.  
  146. #ifndef _ISOSTR_
  147. #include <ISOStr.h>
  148. #endif
  149.  
  150. #ifndef _DOCUTILS_
  151. #include <DocUtils.h>
  152. #endif
  153.  
  154. #ifndef _ODMEMORY_
  155. #include <ODMemory.h>
  156. #endif
  157.  
  158. #ifdef __SC__
  159. #ifndef __PACKAGES__
  160. #include <Packages.h>
  161. #endif
  162. #else
  163. #ifndef __TEXTUTILS__
  164. #include <TextUtils.h>
  165. #endif
  166. #endif
  167.  
  168. #ifndef __STRING__
  169. #include <String.h>
  170. #endif
  171.  
  172. #ifndef __GESTALTEQU__
  173. #include <GestaltEqu.h>
  174. #endif
  175.  
  176. #ifndef __DIALOGS__
  177. #include <Dialogs.h>
  178. #endif
  179.  
  180. #ifndef __TOOLUTILS__
  181. #include <ToolUtils.h>
  182. #endif
  183.  
  184. #ifndef __FONTS__
  185. #include <Fonts.h>
  186. #endif
  187.  
  188. #ifndef __CONTROLS__
  189. #include <Controls.h>
  190. #endif
  191.  
  192. #ifndef __RESOURCES__
  193. #include <Resources.h>
  194. #endif
  195.  
  196. #ifndef _TRANSUTL_
  197. #include <TransUtl.h>
  198. #endif
  199.  
  200. #ifndef __LISTS__
  201. #include <Lists.h>
  202. #endif
  203.  
  204. #ifndef __PALETTES__
  205. #include <Palettes.h>
  206. #endif
  207.  
  208. #ifndef _STORUTIL_
  209. #include <StorUtil.h>
  210. #endif
  211.  
  212. #ifndef _EDITRSET_
  213. #include <EditrSet.h>
  214. #endif
  215.  
  216. #ifndef _STDTYPIO_
  217. #include <StdTypIO.h>
  218. #endif
  219.  
  220. #ifndef _TEMPOBJ_
  221. #include <TempObj.h>
  222. #endif
  223.  
  224. #ifndef _ORDCOLL_
  225. #include "OrdColl.h"
  226. #endif
  227.  
  228. #ifndef SOM_ODStorageSystem_xh
  229. #include "ODStor.xh"
  230. #endif
  231.  
  232. #ifndef _BINDINGUTILS_
  233. #include <BindingUtils.h>
  234. #endif
  235.  
  236. #pragma segment Info
  237.  
  238. #if ODDebug
  239. #define ODDebugLinkDlgs 0
  240. #else
  241. #define ODDebugLinkDlgs 0
  242. #endif
  243.  
  244. //==============================================================================
  245. // Global variables
  246. //==============================================================================
  247.  
  248. // Use a global to pass the current session to the LinkFilterProc
  249. // Globals are per process, and there is only one session per process.
  250. //static ODSession* gSession = kODNULL;
  251.  
  252. static ODName* gKindName = kODNULL;
  253. static ODName* gEditorName = kODNULL;
  254. static ODName* gEmbeddedEditorName = kODNULL;
  255.  
  256. //==============================================================================
  257. // Constants
  258. //==============================================================================
  259.  
  260. const Boolean kNoDefaultButton = kODFalse;
  261.  
  262. const short kButtonFrameInset = -4;
  263.  
  264. const short kControlInactive = 255;
  265. const short kControlActive = 0;
  266.  
  267. // Constants used in list manager calls
  268. const Boolean kDoDraw = true;
  269. const Boolean kNoGrow = false;
  270. const Boolean kIncludeScrollBar = true;
  271.  
  272. // Key codes
  273. // <eeh> moved to DlogUtil.h
  274. // const char kEnterKey        = 0x03;
  275. // const char kReturnKey        = 0x0D;
  276. // const char kEscapeKey        = 0x1B;
  277. // const char kUpArrowKey        = 0x1E;
  278. // const char kDownArrowKey    = 0x1F;
  279.  
  280. //==============================================================================
  281. // Scalar types
  282. //==============================================================================
  283. typedef char ODHandleState;
  284.  
  285. //==============================================================================
  286. // Function declarations
  287. //==============================================================================
  288. ODStatic void SetAsUserItem(DialogPtr dlg, short itemNo, Handle itemUPP);
  289.  
  290. ODStatic void DisposeGlobalODNameAndZeroPtr(ODName** name);
  291.  
  292. ODStatic void SetDateTimeStrings(
  293.                     ODULong        dateTime,
  294.                     Str255        dateString, 
  295.                     Str255        timeString);
  296.  
  297. ODStatic void InitItemActive(
  298.                     DialogPtr    dlg,
  299.                     short        itemNumber,
  300.                     UserItemUPP    itemUPP,
  301.                     ODBoolean    itemActive);
  302.  
  303. ODStatic pascal void DrawDeactivePICTItem(DialogPtr theDialog, short theItem);
  304.  
  305. ODStatic ODBoolean DraftIsReadOnly(Environment* ev, ODStorageUnit* su);
  306.  
  307. ODStatic void SetControlActive(
  308.                     DialogPtr    dlg,
  309.                     short        itemNumber,
  310.                     ODBoolean    itemActive);
  311.  
  312. ODStatic pascal void DrawKindName(DialogPtr dialog, SInt16 item);
  313. ODStatic pascal void DrawEditorName(DialogPtr dialog, SInt16 item);
  314.  
  315. ODStatic void ResetEditorPopup(ODTypeList* kindList,
  316.                                 ODUShort kindIndex,
  317.                                 ODTypeList* translateToList,
  318.                                 ODUShort translateToIndex,
  319.                                 EditorSet* editorList,
  320.                                 MenuHandle editorMenu, 
  321.                                 ControlHandle popupCtlHndl, 
  322.                                 ODSession* session);
  323.  
  324. static pascal Boolean
  325. PasteAsFilterProc(DialogPtr dialog, EventRecord *event, short *itemHit);
  326.  
  327. #ifdef __cplusplus
  328. extern "C" {
  329. #endif
  330.  
  331. ODError ShowPasteAsDialogEx(
  332.                 ODBoolean                canPasteLink,
  333.                 ODPasteAsMergeSetting    mergeSetting,
  334.                 ODBoolean                isMove,
  335.                 ODStorageUnit*            contentSU,
  336.                 ODFacet*                facet,
  337.                 ODTypeToken                viewType,
  338.                 ODPasteAsResult*        result,
  339.                 ODBoolean*                boolResult);
  340.  
  341. ODError ShowLinkSourceInfoEx(
  342.                 ODBaseLinkSource*    linkSource,
  343.                 ODUpdateID            change,
  344.                 ODBoolean            changesAllowed,
  345.                 ODLinkInfoResult*    infoResult,
  346.                 ODBoolean*            boolResult);
  347.  
  348. ODError ShowLinkDestinationInfoEx(
  349.                 ODBaseLink*            link,
  350.                 ODLinkInfo*         info,
  351.                 ODBoolean            changesAllowed,
  352.                 ODLinkInfoResult*    infoResult,
  353.                 ODBoolean*                boolResult);
  354.  
  355. #ifdef __cplusplus
  356. }
  357. #endif
  358.  
  359. //------------------------------------------------------------------------------
  360. // SetAsUserItem
  361. //------------------------------------------------------------------------------
  362.  
  363. ODStatic void SetAsUserItem(DialogPtr dlg, short itemNo, Handle itemUPP)
  364. {
  365.     short     itemType;
  366.     Handle     dummy;
  367.     Rect     itemRect;
  368.     
  369.     GetDialogItem(dlg, itemNo, &itemType, &dummy, &itemRect);
  370.     SetDialogItem(dlg, itemNo, userItem+itemDisable, itemUPP, &itemRect);
  371. }
  372.  
  373. //------------------------------------------------------------------------------
  374. // DisposeGlobalODNameAndZeroPtr
  375. //------------------------------------------------------------------------------
  376. ODStatic void DisposeGlobalODNameAndZeroPtr(ODName** name)
  377. {
  378.     if (*name)
  379.     {
  380.         // simple way to force deletion of old name value without knowing
  381.         // that DisposeIText is the right way to destroy an ODName:
  382.         TempODName tempName = *name;
  383.         *name = kODNULL;
  384.     }
  385. }
  386.  
  387. //------------------------------------------------------------------------------
  388. // DrawEditorName
  389. //------------------------------------------------------------------------------
  390.  
  391. ODStatic pascal void DrawEditorName(DialogPtr dialog, SInt16 item)
  392. {
  393.     short            itemType;
  394.     Handle            itemHandle;
  395.     Rect            itemRect;
  396.  
  397.     GetDialogItem(dialog, item, &itemType, &itemHandle, &itemRect);
  398.  
  399.     if ( gEditorName )
  400.         DrawITextInDlogBox(gEditorName, &itemRect, dialog, kODTrue);
  401. }
  402.  
  403. //------------------------------------------------------------------------------
  404. // DrawEmbeddedEditorName
  405. //------------------------------------------------------------------------------
  406.  
  407. ODStatic pascal void DrawEmbeddedEditorName(DialogPtr dialog, SInt16 item)
  408. {
  409.     short            itemType;
  410.     Handle            itemHandle;
  411.     Rect            itemRect;
  412.  
  413.     GetDialogItem(dialog, item, &itemType, &itemHandle, &itemRect);
  414.  
  415.     if ( gEmbeddedEditorName )
  416.         DrawITextInDlogBox(gEmbeddedEditorName, &itemRect, dialog, kODTrue);
  417. }
  418.  
  419. //------------------------------------------------------------------------------
  420. // GetSelectedType
  421. //------------------------------------------------------------------------------
  422. // $$$$$ Should be replaced by GetThisKindFromList in InfoUtil.h
  423.  
  424. ODStatic ODType GetSelectedType(ODTypeList* typeList, ODSShort typeIndex)
  425. {
  426.     Environment*        ev = somGetGlobalEnvironment();
  427.     ODType                type = kODNULL;
  428.     ODTypeListIterator*    iter = typeList->CreateTypeListIterator(ev);
  429.     
  430.     for ( type = iter->First(ev); 
  431.           (--typeIndex > 0) && iter->IsNotComplete(ev); 
  432.           type = iter->Next(ev) )
  433.     {
  434.         ODDisposePtr(type);
  435.         type = kODNULL;
  436.     }
  437.  
  438.     delete iter;
  439.     
  440.     return type;
  441. }
  442.  
  443. //------------------------------------------------------------------------------
  444. // GetSelectedEditor
  445. //------------------------------------------------------------------------------
  446.  
  447. ODStatic ODEditor GetSelectedEditor(EditorSet* editorList, ODSShort editorIndex)
  448. {
  449.     ODEditor            editor;
  450.     EditorSetIterator*    iter = editorList->CreateIterator();
  451.     
  452.     for ( editor = iter->First(); 
  453.           (--editorIndex > 0) && iter->IsNotComplete(); 
  454.           editor = iter->Next() )
  455.     {
  456.     }
  457.  
  458.     delete iter;
  459.     
  460.     if ( editor != kODNULL )
  461.         editor = ODISOStrFromCStr((char *) editor);
  462.  
  463.     return editor;
  464. }
  465.  
  466. //------------------------------------------------------------------------------
  467. // EnableKindPopupItems
  468. //------------------------------------------------------------------------------
  469.  
  470. ODStatic void EnableKindPopupItems(
  471.                     ODBoolean            forMerge,
  472.                     ODTypeList*            typeList,
  473.                     ODTypeList*            translateList,
  474.                     ODSShort            translationIndex,
  475.                     MenuHandle            kindMenu,
  476.                     ODEditor            editor,
  477.                     ODNameSpaceManager*    nsm)
  478. {
  479.     Environment* ev = somGetGlobalEnvironment();
  480.  
  481.     ODUShort item = EnableTypesInMenu(typeList, kindMenu, forMerge ? editor : kODNULL, nsm);
  482.  
  483.     // If a translation choice is present in the popup, enable it if appropriate;
  484.     if ( translationIndex != 0 )
  485.     {
  486.         TempODType translationKind = GetSelectedType(translateList, translationIndex);
  487.  
  488.         if ( !forMerge || EditorSupportsKind(nsm, editor, translationKind) )
  489.             EnableItem(kindMenu, ++item);
  490.         else
  491.             DisableItem(kindMenu, ++item);
  492.     }
  493.  
  494.     // Enable the "Translate to…" item in the kind popup if translation is possible
  495.     if ( translateList->Count(ev) > 0 )
  496.         EnableItem(kindMenu, ++item);
  497.     else
  498.         DisableItem(kindMenu, ++item);
  499. }
  500.  
  501. //------------------------------------------------------------------------------
  502. // EnablePasteAsOkButton
  503. //------------------------------------------------------------------------------
  504.  
  505. ODStatic void EnablePasteAsOkButton(DialogPtr dlog, MenuHandle kindMenu)
  506. {
  507.     Environment*    ev = somGetGlobalEnvironment();
  508.     short            itemType;
  509.     Handle            itemHandle;
  510.     Rect            itemRect;
  511.     ODSShort        kindItemSelected;
  512.     ODBoolean        shouldBeEnabled;
  513.  
  514.     GetDialogItem(dlog, kPasteAsKindPopup, &itemType, &itemHandle, &itemRect);
  515.     ASSERT_CONTROL_ITEM(itemType);
  516.     kindItemSelected = (ODSShort) GetControlValue((ControlHandle)itemHandle);
  517.  
  518.     // Only the first 31 items of a menu may be disabled
  519.     if ( kindItemSelected > 31 )
  520.         shouldBeEnabled = kODTrue;
  521.     else
  522.         // BitTst numbers the bits hi to low
  523.         shouldBeEnabled = BitTst(&(**kindMenu).enableFlags, 31-kindItemSelected);
  524.  
  525.     EnableOkButton(dlog, shouldBeEnabled);
  526. }
  527.  
  528. //------------------------------------------------------------------------------
  529. // BestMergeKindSetting
  530. //------------------------------------------------------------------------------
  531.  
  532. ODStatic ODSShort BestMergeKindSetting(
  533.                     ODTypeList*            kinds,
  534.                     ODType                bestKind,
  535.                     ODEditor            editor,
  536.                     ODNameSpaceManager*    nsm)
  537. {
  538.     if ( bestKind && EditorSupportsKind(nsm, editor, bestKind) )
  539.         return IndexOfKindInList(kinds, bestKind);
  540.     
  541.     Environment*        ev = somGetGlobalEnvironment();
  542.     ODSShort            kindItem = 0;        // Default in case none are supported
  543.  
  544.     ODTypeListIterator*    iter = kinds->CreateTypeListIterator(ev);
  545.     
  546.     ODType                type;
  547.     ODSShort            i;
  548.     for ( type = iter->First(ev), i = 1; 
  549.           iter->IsNotComplete(ev); 
  550.           type = iter->Next(ev), ++i )
  551.     {
  552.         ODBoolean supports = EditorSupportsKind(nsm, editor, type);
  553.         ODDisposePtr(type);
  554.         if ( supports )
  555.         {
  556.             kindItem = i;
  557.             break;
  558.         }
  559.     }
  560.  
  561.     delete iter;
  562.     
  563.     return kindItem;
  564. }
  565.  
  566. //------------------------------------------------------------------------------
  567. // InitialViewSelection
  568. //------------------------------------------------------------------------------
  569. ODStatic void InitialViewSelection(DialogPtr dlg, ODTypeToken viewType, ODSession* session)
  570. {
  571.     short        itemType;
  572.     Handle        itemHandle;
  573.     Rect        itemRect;
  574.     ODSShort    viewItem;
  575.     
  576.     Environment* ev = somGetGlobalEnvironment();
  577.  
  578.     if (viewType == session->Tokenize(ev, kODViewAsFrame))
  579.         viewItem = kODPasteAsFrameMenuItem;
  580.     else if (viewType == session->Tokenize(ev, kODViewAsLargeIcon))
  581.         viewItem = kODPasteAsLargeIconMenuItem;
  582.     else if (viewType == session->Tokenize(ev, kODViewAsSmallIcon))
  583.         viewItem = kODPasteAsSmallIconMenuItem;
  584.     else if (viewType == session->Tokenize(ev, kODViewAsThumbnail))
  585.         viewItem = kODPasteAsThumbnailMenuItem;
  586.     else
  587.         viewItem = kODPasteAsFrameMenuItem;
  588.  
  589.     GetDialogItem(dlg, kPasteAsEmbedPopup, &itemType, &itemHandle, &itemRect);
  590.     ASSERT_CONTROL_ITEM(itemType);
  591.     SetControlValue((ControlHandle)itemHandle, viewItem);
  592. }
  593.  
  594. //------------------------------------------------------------------------------
  595. // GetViewSelected
  596. //------------------------------------------------------------------------------
  597. ODStatic ODTypeToken GetViewSelected(DialogPtr dlg, ODSession* session)
  598. {
  599.     short        itemType;
  600.     Handle        itemHandle;
  601.     Rect        itemRect;
  602.  
  603.     Environment* ev = somGetGlobalEnvironment();
  604.  
  605.     GetDialogItem(dlg, kPasteAsEmbedPopup, &itemType, &itemHandle, &itemRect);
  606.     ASSERT_CONTROL_ITEM(itemType);
  607.     ODSShort viewItem = (ODSShort) GetControlValue((ControlHandle)itemHandle);
  608.     ODType viewAs;
  609.     switch ( viewItem )
  610.     {
  611.     case kODPasteAsLargeIconMenuItem:
  612.             viewAs = kODViewAsLargeIcon;
  613.             break;
  614.     case kODPasteAsSmallIconMenuItem:
  615.             viewAs = kODViewAsSmallIcon;
  616.             break;
  617.     case kODPasteAsThumbnailMenuItem:
  618.             viewAs = kODViewAsThumbnail;
  619.             break;
  620.     default:
  621.             viewAs = kODViewAsFrame;
  622.             break;
  623.     }
  624.  
  625.     return session->Tokenize(ev, viewAs);
  626. }
  627.  
  628. //------------------------------------------------------------------------------
  629. // HaveColorQuickdraw
  630. //------------------------------------------------------------------------------
  631. ODStatic ODBoolean HaveColorQuickdraw()
  632. {
  633.     long response;
  634.  
  635.     Gestalt(gestaltQuickdrawFeatures, &response);
  636.         
  637.     /* check if Color QuickDraw is available */    
  638.     return BitTst(&response, 31-gestaltHasColor);
  639. }
  640.  
  641. //------------------------------------------------------------------------------
  642. // SetupControlItem
  643. //------------------------------------------------------------------------------
  644. ODStatic void SetupControlItem(
  645.                     DialogPtr    dlg,
  646.                     short        itemNumber,
  647.                     short        itemValue,
  648.                     ODBoolean    itemActive)
  649. {
  650.     short        itemType;
  651.     Handle        itemHandle;
  652.     Rect        itemRect;
  653.  
  654.     GetDialogItem(dlg, itemNumber, &itemType, &itemHandle, &itemRect);
  655.     ASSERT_CONTROL_ITEM(itemType);
  656.     SetControlValue((ControlHandle)itemHandle, itemActive? itemValue : 0);
  657.     HiliteControl((ControlHandle)itemHandle, itemActive ? kControlActive : kControlInactive);
  658. }
  659.  
  660. //------------------------------------------------------------------------------
  661. // InactivateEmbedAsPopup
  662. //------------------------------------------------------------------------------
  663.  
  664. ODStatic void InactivateEmbedAsPopup(DialogPtr dlg)
  665. // Set clipping to just the display area of the popup so the radio button
  666. // label isn't dimmed.
  667. {
  668.     short        aItem;
  669.     Handle        aHandle;
  670.     Handle        embedPopupCntlHandle;
  671.     Rect        aRect;
  672.     RgnHandle    embedTextRgn = ODNewRgn();
  673.     RgnHandle    embedPopupRgn = ODNewRgn();
  674.     RgnHandle    clipRgn = ODNewRgn();
  675.  
  676.     GetDialogItem(dlg, kPasteAsEmbedRadioBtn, &aItem, &aHandle, &aRect);
  677.     RectRgn(embedTextRgn,&aRect);
  678.  
  679.     GetDialogItem(dlg, kPasteAsEmbedPopup, &aItem, &embedPopupCntlHandle, &aRect);
  680.     RectRgn(embedPopupRgn,&aRect);
  681.  
  682.     GetClip(clipRgn);
  683.     DiffRgn(embedPopupRgn, embedTextRgn, embedPopupRgn);
  684.     SetClip(embedPopupRgn);
  685.     HiliteControl((ControlHandle)embedPopupCntlHandle, kControlInactive);
  686.     SetClip(clipRgn);
  687.     
  688.     ODDisposeHandle((Handle)clipRgn);
  689.     ODDisposeHandle((Handle)embedPopupRgn);
  690.     ODDisposeHandle((Handle)embedTextRgn);
  691. }
  692.  
  693. //------------------------------------------------------------------------------
  694. // ClipOutRect
  695. //------------------------------------------------------------------------------
  696.  
  697. ODStatic RgnHandle ClipOutRect(Rect* r)
  698. {
  699.     RgnHandle    saveRgn = ODNewRgn();
  700.     RgnHandle    rectRgn = ODNewRgn();
  701.     RgnHandle    clipRgn = ODNewRgn();
  702.  
  703.     GetClip(saveRgn);
  704.  
  705.     RectRgn(rectRgn, r);
  706.  
  707.     GetClip(clipRgn);
  708.     DiffRgn(clipRgn, rectRgn, clipRgn);
  709.     SetClip(clipRgn);
  710.  
  711.     ODDisposeHandle((Handle)rectRgn);
  712.     ODDisposeHandle((Handle)clipRgn);
  713.     
  714.     return saveRgn;
  715. }
  716.  
  717. //------------------------------------------------------------------------------
  718. // SetAutomaticUpdateControls
  719. //------------------------------------------------------------------------------
  720. ODStatic void SetAutomaticUpdateControls(DialogPtr dlg, ODBoolean autoUpdateSetting)
  721. {
  722.     short    itemType;
  723.     Handle    itemHandle;
  724.     Rect    itemRect;
  725.  
  726.     GetDialogItem(dlg, kPasteAsAutomaticRadioBtn, &itemType, &itemHandle, &itemRect);
  727.     ASSERT_CONTROL_ITEM(itemType);
  728.     SetControlValue((ControlHandle)itemHandle, autoUpdateSetting);
  729.     GetDialogItem(dlg, kPasteAsManualRadioBtn, &itemType, &itemHandle, &itemRect);
  730.     ASSERT_CONTROL_ITEM(itemType);
  731.     SetControlValue((ControlHandle)itemHandle, !autoUpdateSetting);
  732. }
  733.  
  734. //------------------------------------------------------------------------------
  735. // SetMergeEmbedControls
  736. //------------------------------------------------------------------------------
  737. ODStatic void SetMergeEmbedControls(DialogPtr dlg, ODBoolean mergeSetting)
  738. {
  739.     short    itemType;
  740.     Handle    itemHandle;
  741.     Rect    itemRect;
  742.  
  743.     CUsingLibraryResources r;    // Necessary to change embed popup
  744.  
  745.     GetDialogItem(dlg, kPasteAsMergeRadioBtn, &itemType, &itemHandle, &itemRect);
  746.     ASSERT_CONTROL_ITEM(itemType);
  747.     SetControlValue((ControlHandle)itemHandle, mergeSetting);
  748.     
  749.     GetDialogItem(dlg, kPasteAsEmbedRadioBtn, &itemType, &itemHandle, &itemRect);
  750.     ASSERT_CONTROL_ITEM(itemType);
  751.     SetControlValue((ControlHandle)itemHandle, !mergeSetting);
  752.  
  753.     if ( mergeSetting )
  754.     {
  755.         InactivateEmbedAsPopup(dlg);
  756.     }
  757.     else
  758.     {
  759.         GetDialogItem(dlg, kPasteAsEmbedPopup, &itemType, &itemHandle, &itemRect);
  760.         ASSERT_CONTROL_ITEM(itemType);
  761.         HiliteControl((ControlHandle)itemHandle, kControlActive);
  762.     }
  763. }
  764.  
  765. //------------------------------------------------------------------------------
  766. // GetIndexedElement
  767. //------------------------------------------------------------------------------
  768.  
  769. ODStatic ODULong GetIndexedElement(OrderedCollection* translateFromList, ODULong translationIndex)
  770. {
  771.     OrderedCollectionIterator* oci = translateFromList->CreateIterator();
  772.  
  773.     ODULong elem = 0;
  774.  
  775.     for (    elem = (ODULong) oci->First();
  776.             oci->IsNotComplete(); 
  777.             elem = (ODULong) oci->Next() )
  778.     {
  779.         if ( --translationIndex == 0 )
  780.             break;
  781.     }
  782.  
  783.     ODDeleteObject(oci);
  784.  
  785.     return elem;
  786. }
  787.  
  788. //------------------------------------------------------------------------------
  789. // GetOriginalDraft
  790. //------------------------------------------------------------------------------
  791. // Returns 0 if the original draft is unknown.  This is the case when content
  792. // was placed in the draft without cloning.  This code is dependent on properties
  793. // created by the argument storage unit's container suite.
  794.  
  795.  
  796. static ODULong GetOriginalDraft(Environment* ev, ODDraft* draft)
  797. {
  798.     TempODStorageUnit    draftProperties = draft->AcquireDraftProperties(ev);
  799.     return ODGetULongProp(ev, draftProperties, kODPropOriginalDraft, kODULong);
  800. }
  801.  
  802. //------------------------------------------------------------------------------
  803. // SUClonedFromDraft
  804. //------------------------------------------------------------------------------
  805. // Returns kODTrue is the argument storage unit is the clone of a storage unit
  806. // from the argument draft.  This code is dependent on properties created by
  807. // the argument storage unit's container suite.
  808.  
  809. static ODBoolean SUClonedFromDraft(Environment* ev,
  810.             ODStorageUnit* su,
  811.             ODDraft* draft)
  812. {
  813.     return ((ODDraft*)GetOriginalDraft(ev, su->GetDraft(ev)) == draft &&
  814.             su->Exists(ev, kODPropOriginalID, kODULong, 0));
  815. }
  816.  
  817. //------------------------------------------------------------------------------
  818. // DeactivateModalDialog
  819. //------------------------------------------------------------------------------
  820.  
  821. ODStatic void DeactivateModalDialog(ModalFilterUPP filterProc)
  822. {
  823.     DialogPtr dialog = (DialogPtr) FrontWindow();
  824.  
  825.     if ( dialog )
  826.     {
  827.         EventRecord event;
  828.         
  829.         event.what = activateEvt;
  830.         event.message = (long) dialog;
  831.         event.modifiers = 0;
  832.  
  833.         CallModalFilterProc(filterProc, dialog, &event, 0);
  834.     }
  835. }
  836.  
  837. //------------------------------------------------------------------------------
  838. // ShowPasteAsDialog
  839. //------------------------------------------------------------------------------
  840.  
  841. ODError ShowPasteAsDialogEx(
  842.                 ODBoolean                canPasteLink,
  843.                 ODPasteAsMergeSetting    mergeSetting,
  844.                 ODBoolean                isMove,
  845.                 ODStorageUnit*            contentSU,
  846.                 ODFacet*                facet,
  847.                 ODTypeToken                viewType,
  848.                 ODPasteAsResult*        result,
  849.                 ODBoolean*            boolResult)
  850.  
  851. {
  852.     Environment* ev = somGetGlobalEnvironment();
  853.     ODError err = noErr;
  854.  
  855.     WindowPtr    savePort;                            ODVolatile(savePort);
  856.     GetPort(&savePort);
  857.  
  858.     short          itemHit = kPasteAsCancelBtn;
  859.     short        itemType;
  860.     DialogPtr      dlg = kODNULL;                        ODVolatile(dlg);
  861.     Handle        itemHandle;
  862.     Rect        itemRect;
  863.     Rect        kindPopupRect;
  864.     Rect        editorPopupRect;
  865.     short        kindItemSelected;
  866.     short        kindItemOthers;
  867.     short        kindItemCurrent;
  868.     ODBoolean    kindPopupHasNoTranslationKind = kODTrue;
  869.     ODUShort    translationIndex = 0;
  870.  
  871.     ODSLong        refSaved;
  872.     OSErr        resErr;
  873.  
  874.     ODBoolean    userChangedKind = kODFalse;
  875.  
  876.     ControlHandle kindPopupControlHandle;
  877.     ControlHandle editorPopupControlHandle;
  878.  
  879.     ODEditor mergeEditorID = kODNULL;                ODVolatile(mergeEditorID);
  880.     ODEditor embedEditorID = kODNULL;                ODVolatile(embedEditorID);
  881.     ODEditor preferredEditorID = kODNULL;            ODVolatile(preferredEditorID);
  882.  
  883.     EditorSet* editorList = kODNULL;                ODVolatile(editorList);
  884.  
  885.     ODSShort bestKindIndex = 1;
  886.     ODSShort bestMergeKind = 1;
  887.  
  888.     ODType bestKind = kODNULL;                        ODVolatile(bestKind);
  889.     ODTypeList*    kindList = kODNULL;                    ODVolatile(kindList);
  890.     ODTypeList*    translateToList = kODNULL;            ODVolatile(translateToList);
  891.     OrderedCollection* translateFromList = kODNULL;    ODVolatile(translateFromList);
  892.  
  893.     MenuHandle kindMenu = kODNULL;                    ODVolatile(kindMenu);
  894.     MenuHandle editorMenu = kODNULL;                ODVolatile(editorMenu);
  895.  
  896.     UserItemUPP DrawBoxItemUPP = kODNULL;            ODVolatile(DrawBoxItemUPP);
  897.     UserItemUPP DrawDeactiveItemUPP = kODNULL;        ODVolatile(DrawDeactiveItemUPP);
  898.     UserItemUPP    DrawEditorNameUPP = kODNULL;        ODVolatile(DrawEditorNameUPP);
  899.     UserItemUPP    DrawEmbeddedEditorNameUPP = kODNULL;ODVolatile(DrawEmbeddedEditorNameUPP);
  900.     UserItemUPP    DrawKindNameUPP = kODNULL;            ODVolatile(DrawKindNameUPP);
  901.  
  902.     ModalFilterUPP modalFilter = kODNULL;            ODVolatile(modalFilter);
  903.  
  904.     if ( canPasteLink )
  905.         canPasteLink = contentSU->Exists(ev, kODPropLinkSpec, (ODValueType) kODLinkSpec, 0);
  906.  
  907.     result->pasteLinkSetting = (!isMove) && canPasteLink;
  908.     result->autoUpdateSetting = kODTrue;
  909.     result->selectedKind = (ODType) kODNULL;
  910.     result->translateKind = (ODType) kODNULL;
  911.     result->editor = kODNoEditor;
  912.  
  913.     ODSession* session;
  914.     {
  915.         TempODPart part = facet->GetFrame(ev)->AcquirePart(ev);
  916.         session = part->GetStorageUnit(ev)->GetSession(ev);
  917.     }
  918.  
  919.     
  920.     TRY
  921.         ODBinding* binding = session->GetBinding(ev);
  922.         InitBindingNamespaceUtils(session);
  923.         
  924.         ODNameSpaceManager* nsm = session->GetNameSpaceManager(ev);
  925.  
  926.         session->GetWindowState(ev)->DeactivateFrontWindows(ev);
  927.  
  928.         { TempODPart part = facet->GetFrame(ev)->AcquirePart(ev);
  929.           mergeEditorID = GetCurrentEditorForPart(part);
  930.         }
  931.         
  932.         kindList = session->GetStorageSystem(ev)->CreateTypeList(ev, (ODTypeList*) kODNULL);
  933.         ContentValueTypes(contentSU, kindList);
  934.         ODUShort valueCount = kindList->Count(ev);
  935.         
  936.         // Now get all possible translations from the available kinds
  937.         translateToList = session->GetStorageSystem(ev)->CreateTypeList(ev, (ODTypeList*) kODNULL);
  938.         translateFromList = new OrderedCollection;
  939.         TranslateValueTypes(kindList, translateToList, translateFromList, session);
  940.         
  941.         refSaved = BeginUsingLibraryResources();
  942.         kindMenu = GetMenu(kPasteAsKindPopupMenu);
  943.         resErr = ResError();
  944.         EndUsingLibraryResources(refSaved);
  945.         THROW_IF_NULL(kindMenu, resErr ? resErr : resNotFound);
  946.     
  947.         AddTypesToMenu(kindList, kindMenu, kODNULL, valueCount, kODNULL, session);
  948.         kindItemOthers = CountMItems(kindMenu);
  949.  
  950.         ODBoolean canMerge = (mergeSetting != kODPasteAsEmbedOnly);
  951.         ODBoolean canEmbed = (mergeSetting != kODPasteAsMergeOnly);
  952.  
  953.         result->mergeSetting = (mergeSetting == kODPasteAsMerge) || (mergeSetting == kODPasteAsMergeOnly);
  954.  
  955.         {
  956.             CUsingLibraryResources r;
  957.             dlg = ODGetNewDialog(ev, kPasteAsDlgID, session);
  958.             THROW_IF_NULL(dlg);
  959.             SetPort(dlg);
  960.             SetDialogTextStyle(dlg, kPasteAsDlgID, smCurrentScript);
  961.         }
  962.     
  963. #ifdef _APPLEGUIDE_READY_
  964.         DialogSetUpAppleGuide( dlg, kPasteAsAGButton );
  965. #endif
  966.     
  967.         /* Horizontal line needs to be drawn */
  968.         DrawBoxItemUPP = NewUserItemProc(DrawGrayBoxItem);
  969.         SetDialogItemHandle(dlg, kPasteAsHorizSep, (Handle)DrawBoxItemUPP);
  970.     
  971.         // Create one UPP for all user items used to draw deactive PICTs
  972.         DrawDeactiveItemUPP = NewUserItemProc(DrawDeactivePICTItem);
  973.  
  974.         // Initialize state of "Paste with Link" checkbox and label
  975.         SetupControlItem(dlg, kPasteAsLinkCheckbox, result->pasteLinkSetting, canPasteLink);
  976.         
  977.         // Initialize state of "Get Updates" radio buttons and labels
  978.         if ( result->pasteLinkSetting)
  979.             HideDialogItem(dlg, kPasteAsUpdateDisabledText);
  980.         else
  981.             HideDialogItem(dlg, kPasteAsUpdateText);
  982.  
  983.         SetupControlItem(dlg, kPasteAsAutomaticRadioBtn, result->autoUpdateSetting, result->pasteLinkSetting);
  984.         SetupControlItem(dlg, kPasteAsManualRadioBtn, !result->autoUpdateSetting, result->pasteLinkSetting);
  985.  
  986.         // set up merge picture, radio button, and label
  987.         InitItemActive(dlg, kPasteAsMergePict, DrawDeactiveItemUPP, canMerge);
  988.         SetupControlItem(dlg, kPasteAsMergeRadioBtn, result->mergeSetting, canMerge);
  989.  
  990.         // set up embed picture, radio button, and label
  991.         InitItemActive(dlg, kPasteAsEmbedPict, DrawDeactiveItemUPP, canEmbed);
  992.         SetupControlItem(dlg, kPasteAsEmbedRadioBtn, !result->mergeSetting, canEmbed);
  993.     
  994.         // set up initial "Paste as:" popup selection
  995.         InitialViewSelection(dlg, viewType, session);
  996.  
  997.         // inactivate the "Embed as:" popup if merge is initially selected
  998.         if ( result->mergeSetting )
  999.         {
  1000.             GetDialogItem(dlg, kPasteAsEmbedPopup, &itemType, &itemHandle, &itemRect);
  1001.             ASSERT_CONTROL_ITEM(itemType);
  1002.             HiliteControl((ControlHandle)itemHandle, kControlInactive);
  1003.         }
  1004.  
  1005.         // Determine the indices of the best kind and the best kind that can be merged
  1006.         bestKind = BestContentKind(contentSU);
  1007.         if ( bestKind )
  1008.             bestKindIndex = IndexOfKindInList(kindList, bestKind);
  1009.         if ( bestKindIndex == 0 )    // In case preferred kind property is bogus
  1010.             bestKindIndex = 1;
  1011.  
  1012.         bestMergeKind = BestMergeKindSetting(kindList, bestKind, mergeEditorID, nsm);
  1013.  
  1014.         // Suppress the preferred editor if it doesn't support the preferred kind
  1015.         preferredEditorID = ODGetISOStrProp(ev, contentSU, kODPropPreferredEditor, kODEditor, kODNULL, kODNULL);
  1016.         if ( preferredEditorID && bestKind && !EditorSupportsKind(nsm, preferredEditorID, bestKind) )
  1017.         {
  1018.             ODDisposePtr((ODPtr) preferredEditorID);
  1019.             preferredEditorID = kODNULL;
  1020.         }
  1021.  
  1022. #if ODDebugLinkDlgs
  1023.         somPrintf("ShowPasteAsDialog: mergeSetting = %u, best merge kind = %u\n", mergeSetting, (bestMergeKind != 0));
  1024. #endif
  1025.  
  1026.         // Set up the Kind popup items
  1027.         EnableKindPopupItems(result->mergeSetting, kindList, translateToList, 0, kindMenu, mergeEditorID, nsm);
  1028.         GetDialogItem(dlg, kPasteAsKindPopup, &itemType, (Handle*) &kindPopupControlHandle, &kindPopupRect);
  1029.         ASSERT_CONTROL_ITEM(itemType);
  1030.         SetControlValue(kindPopupControlHandle, result->mergeSetting ? bestMergeKind : bestKindIndex);
  1031.     
  1032.         // Determine if the root storage unit is an existing part from the same draft
  1033.         // as the pasting part
  1034.  
  1035.         ODDraft* partDraft;
  1036.         // Get the draft from the part, not the frame, because the frame's storage
  1037.         // unit is null if non-persistent.
  1038.         {
  1039.             TempODPart part = facet->GetFrame(ev)->AcquirePart(ev);
  1040.             partDraft = part->GetStorageUnit(ev)->GetDraft(ev);
  1041.         }
  1042.         ODBoolean contentIsPart = SUClonedFromDraft(ev, contentSU, partDraft);
  1043.  
  1044.         // Set text of static "Kind:" label
  1045.         DisposeGlobalODNameAndZeroPtr(&gKindName);
  1046.         if ( bestKind && GetUserKindFromKind(nsm, bestKind, &gKindName) )
  1047.         {
  1048.             DrawKindNameUPP = NewUserItemProc(DrawKindName);
  1049.             SetAsUserItem(dlg, kPasteAsKindText, (Handle) DrawKindNameUPP);
  1050.         }
  1051.  
  1052.         // inactivate the "Kind:" popup if embedding is initially selected, the operation is
  1053.         // a move, and a cloned part is in the storage unit (not intrinsic content).
  1054.         if ( (!result->mergeSetting) && isMove && contentIsPart )
  1055.         {
  1056.             HideDialogItem(dlg, kPasteAsKindPopup);
  1057.         }
  1058.         else
  1059.         {
  1060.             HideDialogItem(dlg, kPasteAsKindLabel);
  1061.             HideDialogItem(dlg, kPasteAsKindText);
  1062.         }
  1063.  
  1064.         // Setup the static text for the merge editor
  1065.         DisposeGlobalODNameAndZeroPtr(&gEditorName);
  1066.         if ( mergeEditorID && GetUserEditorFromEditor(nsm, mergeEditorID, &gEditorName) )
  1067.         {
  1068.             DrawEditorNameUPP = NewUserItemProc(DrawEditorName);
  1069.             SetAsUserItem(dlg, kPasteAsEditorText, (Handle) DrawEditorNameUPP);
  1070.         }
  1071.  
  1072.         // Setup the static text for the embedding editor
  1073.         // Since the contentSU will not be cloned during a move in the same document, this is a guess as to the
  1074.         // editor actually bound to the moved frame.
  1075.         if ( preferredEditorID )
  1076.             embedEditorID = ODISOStrFromCStr((char *) preferredEditorID);
  1077.         else
  1078.             embedEditorID = binding->ChooseEditorForPart(ev, contentSU, bestKind);
  1079.         
  1080.         DisposeGlobalODNameAndZeroPtr(&gEmbeddedEditorName);
  1081.         if ( embedEditorID && GetUserEditorFromEditor(nsm, embedEditorID, &gEmbeddedEditorName) )
  1082.         {
  1083.             DrawEmbeddedEditorNameUPP = NewUserItemProc(DrawEmbeddedEditorName);
  1084.             SetAsUserItem(dlg, kPasteAsEmbedEditorText, (Handle) DrawEmbeddedEditorNameUPP);
  1085.         }
  1086.  
  1087.         // Setup the editor popup
  1088.         editorList = new EditorSet;
  1089.         editorList->InitEditorSet();
  1090.  
  1091.         refSaved = BeginUsingLibraryResources();
  1092.         editorMenu = GetMenu(kPasteAsEditorPopupMenu);
  1093.         resErr = ResError();
  1094.         EndUsingLibraryResources(refSaved);
  1095.         THROW_IF_NULL(editorMenu, resErr ? resErr : resNotFound);
  1096.  
  1097.         GetDialogItem(dlg, kPasteAsEditorPopup, &itemType, (Handle*) &editorPopupControlHandle, &editorPopupRect);
  1098.         SetupEditorMenu(bestKind, editorList, editorMenu, editorPopupControlHandle, session);
  1099.  
  1100.         if ( result->mergeSetting )
  1101.         {
  1102.             HideDialogItem(dlg, kPasteAsEditorPopup);
  1103.             HideDialogItem(dlg, kPasteAsEmbedEditorText);
  1104.         }
  1105.         else if ( isMove && contentIsPart )
  1106.         {
  1107.             HideDialogItem(dlg, kPasteAsEditorPopup);
  1108.             HideDialogItem(dlg, kPasteAsEditorText);
  1109.         }
  1110.         else
  1111.         {
  1112.             HideDialogItem(dlg, kPasteAsEditorLabel);
  1113.             HideDialogItem(dlg, kPasteAsEmbedEditorText);
  1114.             HideDialogItem(dlg, kPasteAsEditorText);
  1115.         }
  1116.         
  1117.         modalFilter = GetODDialogFilter();
  1118.  
  1119.         // Display the dialog
  1120.         ShowWindow(dlg);
  1121.     
  1122.         do {
  1123.             // Remember the currently selected kind
  1124.             kindItemCurrent = (ODSShort) GetControlValue(kindPopupControlHandle);
  1125.  
  1126.             {    CUsingLibraryResources r;
  1127.                 ModalDialog(modalFilter, &itemHit);
  1128.             }
  1129.     
  1130.             switch (itemHit)
  1131.             {
  1132.             case kPasteAsLinkCheckbox:
  1133.                     result->pasteLinkSetting = !result->pasteLinkSetting;
  1134.                     GetDialogItem(dlg, itemHit, &itemType, &itemHandle, &itemRect);
  1135.                     ASSERT_CONTROL_ITEM(itemType);
  1136.                     SetControlValue((ControlHandle)itemHandle, result->pasteLinkSetting);
  1137.  
  1138.                     if ( result->pasteLinkSetting )
  1139.                     {
  1140.                         GetDialogItem(dlg, kPasteAsUpdateDisabledText, &itemType, &itemHandle, &itemRect);
  1141.                         itemRect.left += 16384;
  1142.                         itemRect.right += 16384;
  1143.                         SetDialogItem(dlg, kPasteAsUpdateDisabledText, itemType, itemHandle, &itemRect);
  1144.                         ShowDialogItem(dlg, kPasteAsUpdateText);
  1145.                     }
  1146.                     else
  1147.                     {
  1148.                         GetDialogItem(dlg, kPasteAsUpdateText, &itemType, &itemHandle, &itemRect);
  1149.                         itemRect.left += 16384;
  1150.                         itemRect.right += 16384;
  1151.                         SetDialogItem(dlg, kPasteAsUpdateText, itemType, itemHandle, &itemRect);
  1152.                         ShowDialogItem(dlg, kPasteAsUpdateDisabledText);
  1153.                     }
  1154.  
  1155.                     SetupControlItem(dlg, kPasteAsAutomaticRadioBtn, result->autoUpdateSetting, result->pasteLinkSetting);
  1156.                     SetupControlItem(dlg, kPasteAsManualRadioBtn, !result->autoUpdateSetting, result->pasteLinkSetting);
  1157.                     break;
  1158.     
  1159.             case kPasteAsAutomaticRadioBtn:
  1160.                     result->autoUpdateSetting = kODTrue;
  1161.                     SetAutomaticUpdateControls(dlg, result->autoUpdateSetting);
  1162.                     break;
  1163.     
  1164.             case kPasteAsManualRadioBtn:
  1165.                     result->autoUpdateSetting = kODFalse;
  1166.                     SetAutomaticUpdateControls(dlg, result->autoUpdateSetting);
  1167.                     break;
  1168.     
  1169.             case kPasteAsMergePict:
  1170.             case kPasteAsMergeRadioBtn:
  1171.                     if ( !result->mergeSetting )
  1172.                     {
  1173.                         result->mergeSetting = kODTrue;
  1174.                         SetMergeEmbedControls(dlg, result->mergeSetting);
  1175.  
  1176.                         TempODType selectedKind = kODNULL;
  1177.                         if ( kindItemCurrent <= kindList->Count(ev) )
  1178.                             selectedKind = GetSelectedType(kindList, kindItemCurrent);
  1179.                         else
  1180.                             selectedKind = GetSelectedType(translateToList, translationIndex);
  1181.  
  1182.                         if ( !EditorSupportsKind(nsm, mergeEditorID, selectedKind) )
  1183.                         {
  1184.                             SetPopupControlValue(kindPopupControlHandle, bestMergeKind);
  1185.                             userChangedKind = kODFalse;    // Allow embed to automatically select best kind
  1186.                         }
  1187.  
  1188.                         EnableKindPopupItems(result->mergeSetting, kindList, translateToList, translationIndex, kindMenu, mergeEditorID, nsm);
  1189.     
  1190.                         if ( isMove && contentIsPart )
  1191.                         {
  1192.                             HideDialogItem(dlg, kPasteAsKindLabel);
  1193.                             HideDialogItem(dlg, kPasteAsKindText);
  1194.                             ShowDialogItem(dlg, kPasteAsKindPopup);
  1195.                         }
  1196.                         else
  1197.                         {
  1198.                             EnablePasteAsOkButton(dlg, kindMenu);
  1199.                         }
  1200.                         
  1201.                         HideDialogItem(dlg, kPasteAsEditorPopup);
  1202.                         HideDialogItem(dlg, kPasteAsEmbedEditorText);
  1203.                         ShowDialogItem(dlg, kPasteAsEditorLabel);
  1204.                         ShowDialogItem(dlg, kPasteAsEditorText);
  1205.                     }
  1206.                     break;
  1207.     
  1208.             case kPasteAsEmbedPict:
  1209.             case kPasteAsEmbedRadioBtn:
  1210.                     if ( result->mergeSetting )
  1211.                     {
  1212.                         result->mergeSetting = kODFalse;
  1213.                         SetMergeEmbedControls(dlg, result->mergeSetting);
  1214.     
  1215.                         // If the user has not changed the kind setting, switch to the preferred kind
  1216.                         kindItemSelected = (ODSShort) GetControlValue(kindPopupControlHandle);
  1217.                         if ( !userChangedKind )
  1218.                         {
  1219.                             // Make sure item is enabled before drawing it!
  1220.                             EnableItem(kindMenu, bestKindIndex);
  1221.                             SetPopupControlValue(kindPopupControlHandle, bestKindIndex);
  1222.                             kindItemSelected = bestKindIndex;
  1223.                         }
  1224.  
  1225.                         // When embedding is chosen, determine the preferred editor, then enable the kind menu
  1226.                         ResetEditorPopup(kindList,
  1227.                                         kindItemSelected,
  1228.                                         translateToList,
  1229.                                         translationIndex,
  1230.                                         editorList,
  1231.                                         editorMenu, 
  1232.                                         editorPopupControlHandle, 
  1233.                                         session);
  1234.  
  1235.                         // Select the preferred editor if specified
  1236.                         ODSShort preferredEditorItem = IndexOfEditorInList(editorList, preferredEditorID);
  1237.                         if ( preferredEditorItem != 0 )
  1238.                             SetPopupControlValue(editorPopupControlHandle, preferredEditorItem);
  1239.  
  1240.                         if ( isMove && contentIsPart )
  1241.                         {
  1242.                             HideDialogItem(dlg, kPasteAsEditorText);
  1243.                             ShowDialogItem(dlg, kPasteAsEmbedEditorText);
  1244.                         }
  1245.                         else
  1246.                         {
  1247.                             HideDialogItem(dlg, kPasteAsEditorLabel);
  1248.                             HideDialogItem(dlg, kPasteAsEditorText);
  1249.                             ShowDialogItem(dlg, kPasteAsEditorPopup);
  1250.                         }
  1251.  
  1252.                         // Now enable the kind items
  1253.                         if ( isMove && contentIsPart )
  1254.                         {
  1255.                             HideDialogItem(dlg, kPasteAsKindPopup);
  1256.                             ShowDialogItem(dlg, kPasteAsKindLabel);
  1257.                             ShowDialogItem(dlg, kPasteAsKindText);
  1258.                         }
  1259.                         else
  1260.                         {
  1261.                             ODSShort editorItem = (ODSShort) GetControlValue(editorPopupControlHandle);
  1262.                             ODEditor selectedEditor = GetSelectedEditor(editorList, editorItem);
  1263.                             EnableKindPopupItems(result->mergeSetting, kindList, translateToList, translationIndex, kindMenu, selectedEditor, nsm);
  1264.                             ODDisposePtr((ODPtr) selectedEditor);
  1265.                             EnablePasteAsOkButton(dlg, kindMenu);
  1266.                         }
  1267.                     }
  1268.                     break;
  1269.     
  1270.             case kPasteAsKindPopup:
  1271.                     kindItemSelected = (ODSShort) GetControlValue(kindPopupControlHandle);
  1272.                     if ( kindItemSelected == kindItemOthers )
  1273.                     {
  1274.                         ODUShort selectedIndex;
  1275.                         ODSShort editorItem = (ODSShort) GetControlValue(editorPopupControlHandle);
  1276.                         ODEditor initialEditorID;
  1277.                         if ( result->mergeSetting )
  1278.                             initialEditorID = ODISOStrFromCStr((char *) mergeEditorID);
  1279.                         else
  1280.                             initialEditorID = GetSelectedEditor(editorList, editorItem);
  1281.                         ODEditor newEditorID = kODNULL;
  1282.  
  1283.                         // Return the kind popup to its current value 
  1284.                         SetPopupControlValue(kindPopupControlHandle, kindItemCurrent);
  1285.                         ActivateAllControls(dlg, kODFalse); // deactivate control
  1286.  
  1287.                         if ( session->GetTranslation(ev)->ShowTranslateDialog(
  1288.                                                                 ev,
  1289.                                                                 translateToList,
  1290.                                                                 translationIndex,
  1291.                                                                 &selectedIndex,
  1292.                                                                 initialEditorID,
  1293.                                                                 !result->mergeSetting,
  1294.                                                                 &newEditorID) )
  1295.                         {
  1296.                             // Add translationKind to the list just above "Translate to…", 
  1297.                             //  and make it the current selection.
  1298.                             translationIndex = selectedIndex;
  1299.  
  1300.                             { TempODType translationKind = GetSelectedType(translateToList, translationIndex);
  1301.                               AddTranslationKindToMenu(translationKind, kindMenu, kindItemOthers-1, 
  1302.                                                         kindPopupHasNoTranslationKind, session);
  1303.                             }
  1304.  
  1305.                             if ( kindPopupHasNoTranslationKind )
  1306.                             {
  1307.                                 kindPopupHasNoTranslationKind = kODFalse;
  1308.                                 kindItemOthers += 1;
  1309.                             }
  1310.  
  1311.                             SetPort(dlg);
  1312.                             SetControlValue(kindPopupControlHandle, kindItemOthers-1);
  1313.                             InvalRect(&kindPopupRect);    // Redraw the popup
  1314.  
  1315.                             if ( !result->mergeSetting )
  1316.                             {
  1317.                                 ResetEditorPopup(kindList,
  1318.                                                 kindItemSelected,
  1319.                                                 translateToList,
  1320.                                                 translationIndex,
  1321.                                                 editorList,
  1322.                                                 editorMenu, 
  1323.                                                 editorPopupControlHandle, 
  1324.                                                 session);
  1325.                                 // Select editorID in the list
  1326.                                 ODSShort editorItem = IndexOfEditorInList(editorList, newEditorID);
  1327.                                 if ( editorItem != 0 )
  1328.                                     SetControlValue(editorPopupControlHandle, editorItem);
  1329.                                 InvalRect(&editorPopupRect);    // Redraw the popup
  1330.                             }
  1331.                             ODDisposePtr((ODPtr) initialEditorID);
  1332.                             ODDisposePtr((ODPtr) newEditorID);
  1333.  
  1334.                             userChangedKind = kODTrue;
  1335.                         }
  1336.                         ActivateAllControls(dlg, kODTrue);    // reactivate control
  1337.                     }
  1338.                     else if ( kindItemSelected != kindItemCurrent )
  1339.                     {
  1340.                         userChangedKind = kODTrue;
  1341.                         if ( !result->mergeSetting )
  1342.                         {
  1343.                             // Remember the currently selected editor
  1344.                             ODSShort editorItem = (ODSShort) GetControlValue(editorPopupControlHandle);
  1345.                             TempODEditor lastEditorID = GetSelectedEditor(editorList, editorItem);
  1346.  
  1347.                             ResetEditorPopup(kindList,
  1348.                                             kindItemSelected,
  1349.                                             translateToList,
  1350.                                             translationIndex,
  1351.                                             editorList,
  1352.                                             editorMenu, 
  1353.                                             editorPopupControlHandle, 
  1354.                                             session);
  1355.  
  1356.                             // Reselect the last editor if it supports the new kind
  1357.                             TempODType selectedKind = kODNULL;
  1358.                             if ( kindItemCurrent <= kindList->Count(ev) )
  1359.                                 selectedKind = GetSelectedType(kindList, kindItemCurrent);
  1360.                             else
  1361.                                 selectedKind = GetSelectedType(translateToList, translationIndex);
  1362.  
  1363.                             ODSShort newEditorItem = 0;
  1364.                             if ( EditorSupportsKind(nsm, lastEditorID, selectedKind) )
  1365.                             {
  1366.                                 newEditorItem = IndexOfEditorInList(editorList, lastEditorID);
  1367.                             }
  1368.                             if ( newEditorItem != 0 )
  1369.                                 SetPopupControlValue(editorPopupControlHandle, newEditorItem);
  1370.                             else
  1371.                             {
  1372.                             SetPort(dlg);
  1373.                             InvalRect(&editorPopupRect);    // Redraw the popup
  1374.                         }
  1375.                     }
  1376.                     }
  1377.                     EnablePasteAsOkButton(dlg, kindMenu);
  1378.                     break;
  1379. #ifdef _APPLEGUIDE_READY_
  1380.             case kPasteAsAGButton:
  1381.                 OpenAppleGuide( ODGetIndShort( kODShellGuideSearchIndices,
  1382.                         kODShellGuideStringIndexPasteAs ) );
  1383.                 break;
  1384. #endif
  1385.             default:
  1386.                     break;
  1387.             }
  1388.         } while ((itemHit != kPasteAsOKBtn) && (itemHit != kPasteAsCancelBtn));
  1389.         
  1390.         if ( itemHit == kPasteAsOKBtn )
  1391.         {
  1392.             // update from "View" popup
  1393.             if ( !result->mergeSetting )
  1394.                 result->selectedView = GetViewSelected(dlg, session);
  1395.     
  1396.             // update from "Kind" popup
  1397.             if ( (!result->mergeSetting) && isMove && contentIsPart )
  1398.             {
  1399.                 // Selected kind is the best kind
  1400.                 result->selectedKind = GetSelectedType(kindList, bestKindIndex);
  1401.             }
  1402.             else
  1403.             {
  1404.                 ODSShort kindItem = (ODSShort) GetControlValue(kindPopupControlHandle);
  1405.                 ODSShort kindCount = (ODSShort) kindList->Count(ev);
  1406.                 if (kindItem <= kindCount)
  1407.                 {
  1408.                     result->selectedKind = GetSelectedType(kindList, kindItem);
  1409.                 }
  1410.                 else
  1411.                 {
  1412.                     result->selectedKind = GetSelectedType(translateToList, translationIndex);
  1413.                     result->translateKind = GetSelectedType(kindList, GetIndexedElement(translateFromList, translationIndex));
  1414.                 }
  1415.             }
  1416.  
  1417.             // update from "Editor" popup
  1418.             if ( (!result->mergeSetting) && (!isMove || !contentIsPart) )
  1419.             {
  1420.                 ODSShort editorItem = (ODSShort) GetControlValue(editorPopupControlHandle);
  1421.                 result->editor = GetSelectedEditor(editorList, editorItem);
  1422.             }
  1423.         }
  1424.     
  1425.     CATCH_ALL
  1426.  
  1427. //        RERAISE;
  1428.         err = ErrorCode();
  1429.     ENDTRY;
  1430.  
  1431.     ODDisposeRoutineDescriptor(DrawBoxItemUPP);
  1432.     ODDisposeRoutineDescriptor(DrawDeactiveItemUPP);
  1433.     ODDisposeRoutineDescriptor(DrawKindNameUPP);
  1434.     ODDisposeRoutineDescriptor(DrawEditorNameUPP);
  1435.     ODDisposeRoutineDescriptor(DrawEmbeddedEditorNameUPP);
  1436.  
  1437.     refSaved = BeginUsingLibraryResources();
  1438.     if ( kindMenu )
  1439.     {
  1440.         DeleteMenu(kPasteAsKindPopupMenu);
  1441.         ReleaseResource((Handle) kindMenu);
  1442.     }
  1443.     if ( editorMenu )
  1444.     {
  1445.         DeleteMenu(kPasteAsEditorPopupMenu);
  1446.         ReleaseResource((Handle) editorMenu);
  1447.     }
  1448.     ODDisposeDialog(dlg);
  1449.     EndUsingLibraryResources(refSaved);
  1450.  
  1451.     ODDisposePtr((ODPtr) mergeEditorID);
  1452.     ODDisposePtr((ODPtr) embedEditorID);
  1453.     ODDisposePtr((ODPtr) preferredEditorID);
  1454.     ODDisposePtr((ODPtr) bestKind);
  1455.  
  1456.     ODDeleteObject(kindList);
  1457.     ODDeleteObject(translateToList);
  1458.     ODDeleteObject(translateFromList);
  1459.     delete editorList; editorList = kODNULL;
  1460.  
  1461.     DisposeGlobalODNameAndZeroPtr(&gEditorName);
  1462.     DisposeGlobalODNameAndZeroPtr(&gEmbeddedEditorName);
  1463.  
  1464.     session->GetWindowState(ev)->ActivateFrontWindows(ev);
  1465.  
  1466.     SetPort(savePort);
  1467.  
  1468.     *boolResult = (itemHit == kPasteAsOKBtn);
  1469.     return err;
  1470. }
  1471.  
  1472. //------------------------------------------------------------------------------
  1473. // ResetEditorPopup
  1474. //------------------------------------------------------------------------------
  1475.  
  1476. ODStatic void ResetEditorPopup(ODTypeList* kindList,
  1477.                                 ODUShort kindIndex,
  1478.                                 ODTypeList* translateToList,
  1479.                                 ODUShort translateToIndex,
  1480.                                 EditorSet* editorList,
  1481.                                 MenuHandle editorMenu, 
  1482.                                 ControlHandle popupCtlHndl, 
  1483.                                 ODSession* session)
  1484. {
  1485.     Environment* ev = somGetGlobalEnvironment();
  1486.     TempODType kind = kODNULL;
  1487.  
  1488.     ODSShort kindCount = (ODSShort) kindList->Count(ev);
  1489.     if (kindIndex <= kindCount)
  1490.         kind = GetSelectedType(kindList, kindIndex);
  1491.     else
  1492.         kind = GetSelectedType(translateToList, translateToIndex);
  1493.  
  1494.     editorList->RemoveAllEditors();
  1495.     SetupEditorMenu(kind,
  1496.                     editorList,
  1497.                     editorMenu,
  1498.                     popupCtlHndl,
  1499.                     session);
  1500. }
  1501.  
  1502. //------------------------------------------------------------------------------
  1503. // PrepareToDrawGray
  1504. //------------------------------------------------------------------------------
  1505. //
  1506. // Sets the foreground color to the best color midway between the forground and
  1507. // background colors; usually gray.  If no intermediate gray is available (4 or
  1508. // fewer colors available), the pen pattern is set to draw gray.
  1509.  
  1510. ODStatic Boolean PrepareToDrawGray(DialogPtr theDialog, short theItem, RGBColor* fgSaveColor)
  1511. {
  1512.     Boolean result = false;
  1513.     const short kColorPort = 0xC000;
  1514.     
  1515.     Boolean isColorPort = ((((CGrafPtr)theDialog)->portVersion & kColorPort) == kColorPort);
  1516.     
  1517.     if ( isColorPort )
  1518.     {
  1519.         RGBColor    fgNewColor;
  1520.         RGBColor    bgColor;
  1521.  
  1522.         Rect         itemRect;
  1523.         Handle        itemHandle;
  1524.         short        itemKind;
  1525.  
  1526.         GetBackColor(&bgColor);
  1527.         GetForeColor(fgSaveColor);
  1528.         fgNewColor = *fgSaveColor;
  1529.         
  1530.         GetDialogItem(theDialog, kPasteAsOKBtn, &itemKind, &itemHandle, &itemRect);
  1531.  
  1532.         Rect globalRect = itemRect;
  1533.         LocalToGlobal((Point *)&(globalRect.top));
  1534.         LocalToGlobal((Point *)&(globalRect.bottom));
  1535.         GDHandle targetDevice = GetMaxDevice(&globalRect);
  1536.         
  1537.         result = GetGray(targetDevice, &bgColor, &fgNewColor);
  1538.  
  1539.         if ( result )
  1540.             RGBForeColor(&fgNewColor);
  1541.     }
  1542.     
  1543.     if ( !result )
  1544.     {
  1545. #ifdef THINK_CPLUS
  1546.         PenPat(ODQDGlobals.gray);
  1547. #else
  1548.         PenPat(&ODQDGlobals.gray);
  1549. #endif
  1550.     }
  1551.  
  1552.     return result;
  1553. }
  1554.  
  1555. //------------------------------------------------------------------------------
  1556. // DrawDeactivePICTItem
  1557. //------------------------------------------------------------------------------
  1558. //
  1559. // Draws a dimmed image of the preceeding dialog item, which should be
  1560. // beyond the visible area of the dialog, in this item's rectangle.
  1561.  
  1562. ODStatic pascal void DrawDeactivePICTItem(DialogPtr theDialog, short theItem)
  1563. {
  1564.     Rect         itemRect, otherRect;
  1565.     Handle        itemHandle, otherHandle;
  1566.     short        itemKind, otherKind;
  1567.  
  1568.     WindowPtr    savePort;
  1569.     PenState    savePen;
  1570.     
  1571.     RGBColor    fgSaveColor;
  1572.     Boolean        isColor;
  1573.  
  1574.     GetPort(&savePort);
  1575.     SetPort(theDialog);
  1576.     GetPenState(&savePen);
  1577.     PenNormal();
  1578.  
  1579.     // Get this dialog item
  1580.     GetDialogItem(theDialog, theItem, &itemKind, &itemHandle, &itemRect);
  1581.  
  1582.     // Get the dialog item to be drawn disabled
  1583.     GetDialogItem(theDialog, theItem-1, &otherKind, &otherHandle, &otherRect);
  1584.     if ( (otherKind & ~itemDisable) == picItem )
  1585.     {
  1586.         DrawPicture((PicHandle) otherHandle, &itemRect);
  1587.         isColor = PrepareToDrawGray(theDialog, theItem, &fgSaveColor);
  1588.         if ( isColor )
  1589.             PenMode(addMax);
  1590.         else
  1591.             PenMode(patBic);
  1592.         PaintRect(&itemRect);
  1593.         if ( isColor )
  1594.             RGBForeColor(&fgSaveColor);
  1595.     }
  1596.  
  1597.     SetPenState(&savePen);
  1598.     SetPort(savePort);
  1599. }
  1600.  
  1601. //------------------------------------------------------------------------------
  1602. // InitItemActive
  1603. //------------------------------------------------------------------------------
  1604.  
  1605. ODStatic void InitItemActive(
  1606.                     DialogPtr    dlg,
  1607.                     short        itemNumber,
  1608.                     UserItemUPP    itemUPP,
  1609.                     ODBoolean    itemActive)
  1610. {
  1611.     Rect         itemRect, otherRect;
  1612.     Handle        itemHandle, otherHandle;
  1613.     short        itemKind, otherKind;
  1614.  
  1615.     // Get the rectangle from the actual item
  1616.     GetDialogItem(dlg, itemNumber, &otherKind, &otherHandle, &otherRect);
  1617.  
  1618.     // Establish the draw routine and rectangle for the user item
  1619.     GetDialogItem(dlg, itemNumber+1, &itemKind, &itemHandle, &itemRect);
  1620.     SetDialogItem(dlg, itemNumber+1, itemKind, (Handle)itemUPP, &otherRect);
  1621.  
  1622.     if ( itemActive )
  1623.         HideDialogItem(dlg, itemNumber+1);
  1624.     else
  1625.         HideDialogItem(dlg, itemNumber);
  1626. }
  1627.  
  1628. //------------------------------------------------------------------------------
  1629. // SetControlActive
  1630. //------------------------------------------------------------------------------
  1631. ODStatic void SetControlActive(
  1632.                     DialogPtr    dlg,
  1633.                     short        itemNumber,
  1634.                     ODBoolean    itemActive)
  1635. {
  1636.     short        itemType;
  1637.     Handle        itemHandle;
  1638.     Rect        itemRect;
  1639.  
  1640.     GetDialogItem(dlg, itemNumber, &itemType, &itemHandle, &itemRect);
  1641.     ASSERT_CONTROL_ITEM(itemType);
  1642.     HiliteControl((ControlHandle)itemHandle, itemActive ? kControlActive : kControlInactive);
  1643. }
  1644.  
  1645. //------------------------------------------------------------------------------
  1646. // SetLinkUpdateUpdateControls
  1647. //------------------------------------------------------------------------------
  1648. ODStatic void SetLinkUpdateUpdateControls(DialogPtr dlg, ODBoolean autoUpdateSetting)
  1649. {
  1650.     short    itemType;
  1651.     Handle    itemHandle;
  1652.     Rect    itemRect;
  1653.  
  1654.     GetDialogItem(dlg, kLinkInfoOnSaveRadioBtn, &itemType, &itemHandle, &itemRect);
  1655.     ASSERT_CONTROL_ITEM(itemType);
  1656.     SetControlValue((ControlHandle)itemHandle, autoUpdateSetting);
  1657.     GetDialogItem(dlg, kLinkInfoManualRadioBtn, &itemType, &itemHandle, &itemRect);
  1658.     ASSERT_CONTROL_ITEM(itemType);
  1659.     SetControlValue((ControlHandle)itemHandle, !autoUpdateSetting);
  1660. }
  1661.  
  1662. //------------------------------------------------------------------------------
  1663. // ShowLinkInfo
  1664. //------------------------------------------------------------------------------
  1665.  
  1666. ODStatic ODBoolean ShowLinkInfo(
  1667.                         DialogPtr              dlg,
  1668.                         ConstStr255Param    creationDate,
  1669.                         ConstStr255Param    creationTime,
  1670.                         ConstStr255Param    modificationDate,
  1671.                         ConstStr255Param    modificationTime,
  1672.                         ODBoolean            needsUpdate,
  1673.                         ODLinkInfoResult*    infoResult,
  1674.                         short                agStringIndex
  1675.                         )
  1676. {
  1677.     short    itemHit;
  1678.  
  1679.     ParamText(creationDate, creationTime, modificationDate, modificationTime);
  1680.  
  1681.     ShowWindow(dlg);
  1682.     
  1683.     ModalFilterUPP modalFilter = GetODDialogFilter();
  1684.  
  1685.     do {
  1686.         ODSLong refSaved = BeginUsingLibraryResources();
  1687.         ModalDialog(modalFilter, &itemHit);
  1688.         EndUsingLibraryResources(refSaved);
  1689.  
  1690.         switch (itemHit)
  1691.         {
  1692.         case kLinkInfoManualRadioBtn :
  1693.             if ( infoResult->autoUpdate )
  1694.             {
  1695.                 infoResult->autoUpdate = kODFalse;
  1696.                 SetLinkUpdateUpdateControls(dlg, infoResult->autoUpdate);
  1697.                 SetControlActive(dlg, kLinkInfoUpdateBtn, needsUpdate);
  1698.             }
  1699.             break;
  1700.             
  1701.         case kLinkInfoOnSaveRadioBtn :
  1702.             if ( !infoResult->autoUpdate )
  1703.             {
  1704.                 infoResult->autoUpdate = kODTrue;
  1705.                 SetLinkUpdateUpdateControls(dlg, infoResult->autoUpdate);
  1706.                 SetControlActive(dlg, kLinkInfoUpdateBtn, kODFalse);
  1707.             }
  1708.             break;
  1709. #ifdef _APPLEGUIDE_READY_
  1710.         case kLinkInfoAGButton:
  1711.             OpenAppleGuide( ODGetIndShort( kODShellGuideSearchIndices,
  1712.                     agStringIndex ) );
  1713.             break;
  1714. #endif
  1715.         }
  1716.     } while ((itemHit != kLinkInfoOKBtn) && (itemHit != kLinkInfoCancelBtn) &&
  1717.              (itemHit != kLinkInfoUpdateBtn) && (itemHit != kLinkInfoBreakLinkBtn) &&
  1718.              (itemHit != kLinkInfoFindSrcBtn));
  1719.  
  1720.     switch (itemHit) {
  1721.     case kLinkInfoOKBtn:
  1722.             infoResult->action = kODLinkInfoOk;
  1723.             break;
  1724.     case kLinkInfoUpdateBtn:
  1725.             infoResult->action = kODLinkInfoUpdateNow;
  1726.             break;
  1727.     case kLinkInfoBreakLinkBtn:
  1728.             infoResult->action = kODLinkInfoBreakLink;
  1729.             break;
  1730.     case kLinkInfoFindSrcBtn:
  1731.             infoResult->action = kODLinkInfoFindSource;
  1732.             break;
  1733.     default:
  1734.             infoResult->action = kODLinkInfoCancel;
  1735.             break;
  1736.     }
  1737.  
  1738.     return (itemHit != kLinkInfoCancelBtn);
  1739. }
  1740.  
  1741. //------------------------------------------------------------------------------
  1742. // DrawKindName
  1743. //------------------------------------------------------------------------------
  1744.  
  1745. pascal void DrawKindName(DialogPtr dialog, SInt16 item)
  1746. {
  1747.     short    itemType;
  1748.     Handle    itemHandle;
  1749.     Rect    itemRect;
  1750.  
  1751.     GetDialogItem(dialog, item, &itemType, &itemHandle, &itemRect);
  1752.  
  1753.     DrawITextInDlogBox(gKindName, &itemRect, dialog, kODTrue);
  1754. }
  1755.  
  1756. //------------------------------------------------------------------------------
  1757. // ShowLinkSourceInfo
  1758. //------------------------------------------------------------------------------
  1759.  
  1760. ODError ShowLinkSourceInfoEx(
  1761.                 ODBaseLinkSource*    linkSource,
  1762.                 ODUpdateID            change,
  1763.                 ODBoolean            changesAllowed,
  1764.                 ODLinkInfoResult*    infoResult,
  1765.                 ODBoolean*            boolResult)
  1766. {
  1767.     ODError err = noErr;
  1768.     Environment* ev = somGetGlobalEnvironment();
  1769.  
  1770.     WindowPtr    savePort;                        ODVolatile(savePort);
  1771.     GetPort(&savePort);
  1772.     ODSLong        refSaved;
  1773.  
  1774.     DialogPtr      dlg = kODNULL;                    ODVolatile(dlg);
  1775.     UserItemUPP DrawBoxItemUPP = kODNULL;        ODVolatile(DrawBoxItemUPP);
  1776.     UserItemUPP DrawKindNameUPP = kODNULL;        ODVolatile(DrawKindNameUPP);
  1777.     short        itemType;
  1778.     Handle        itemHandle;
  1779.     Rect        itemRect;
  1780.     Str255        creationDate, modificationDate;
  1781.     Str255        creationTime, modificationTime;
  1782.     ODType        kind;
  1783.     ODBoolean    needsUpdate;
  1784.  
  1785.     TRY
  1786.         ODSession* session = linkSource->GetStorageUnit(ev)->GetSession(ev);
  1787.         InitBindingNamespaceUtils(session);
  1788.         
  1789.         ODNameSpaceManager* nsm = session->GetNameSpaceManager(ev);
  1790.         
  1791.         {
  1792.             CUsingLibraryResources r;
  1793.             dlg = ODGetNewDialog(ev, kLinkSrcInfoDlgID, session);
  1794.             THROW_IF_NULL(dlg);
  1795.         }
  1796.  
  1797. #ifdef _APPLEGUIDE_READY_
  1798.         DialogSetUpAppleGuide( dlg, kLinkInfoAGButton );
  1799. #endif
  1800.         SetPort(dlg);
  1801.         
  1802.         {    CUsingLibraryResources r;
  1803.             SetDialogTextStyle(dlg, kLinkSrcInfoDlgID, smCurrentScript);
  1804.         }
  1805.     
  1806.         // Vertical and horizontal lines need to be drawn
  1807.         DrawBoxItemUPP = NewUserItemProc(DrawGrayBoxItem);
  1808.         SetDialogItemHandle(dlg, kLinkInfoSeparator, (Handle)DrawBoxItemUPP);
  1809.         
  1810.         ODLinkKey key;
  1811.         if (linkSource->Lock(ev, 0, &key))
  1812.         {
  1813.             TRY
  1814.                 ODStorageUnit*    contentSU = linkSource->GetContentStorageUnit(ev, key);
  1815.         
  1816.                 // Set up kind
  1817.                 kind = BestContentKind(contentSU);
  1818.                 DisposeGlobalODNameAndZeroPtr(&gKindName);
  1819.                 if ( kind && GetUserKindFromKind(nsm, kind, &gKindName) )
  1820.                 {
  1821.                     DrawKindNameUPP = NewUserItemProc(DrawKindName);
  1822.                     SetAsUserItem(dlg, kLinkInfoKind, (Handle) DrawKindNameUPP);
  1823.                 }
  1824.                 ODDisposePtr((ODPtr) kind);
  1825.     
  1826.                 // Set up creation date
  1827.                 SetDateTimeStrings(ODGetCreationDate(ev, ODGetSUFromPstObj(ev, linkSource)),
  1828.                                     creationDate, creationTime);
  1829.                 
  1830.                 // Set up modified date
  1831.                 SetDateTimeStrings(linkSource->GetChangeTime(ev), modificationDate, modificationTime);
  1832.             CATCH_ALL
  1833.                 linkSource->Unlock(ev, key);
  1834.                 RERAISE;
  1835.             ENDTRY
  1836.     
  1837.             linkSource->Unlock(ev, key);
  1838.         }
  1839.         
  1840.         // Set up Send Updates
  1841.         SetLinkUpdateUpdateControls(dlg, infoResult->autoUpdate);
  1842.         
  1843.         needsUpdate = (change == kODUnknownUpdate) || (change != linkSource->GetUpdateID(ev));
  1844.         
  1845.         // Disable Update Now button if updates are automatic or link is up to date.
  1846.         if ( infoResult->autoUpdate || !needsUpdate )
  1847.         {
  1848.             GetDialogItem(dlg, kLinkInfoUpdateBtn, &itemType, &itemHandle, &itemRect);
  1849.             ASSERT_CONTROL_ITEM(itemType);
  1850.             HiliteControl((ControlHandle)itemHandle, kControlInactive);
  1851.         }
  1852.     
  1853.         // Disable some items if changes are not allowed or draft is read only
  1854.         if ( !changesAllowed || DraftIsReadOnly(ev, linkSource->GetStorageUnit(ev)) )
  1855.         {
  1856.             SetControlActive(dlg, kLinkInfoOnSaveRadioBtn, kODFalse);
  1857.             SetControlActive(dlg, kLinkInfoManualRadioBtn, kODFalse);
  1858.             SetControlActive(dlg, kLinkInfoBreakLinkBtn, kODFalse);
  1859.             SetControlActive(dlg, kLinkInfoUpdateBtn, kODFalse);
  1860.         }
  1861.  
  1862.         *boolResult = ShowLinkInfo(dlg, creationDate, creationTime, modificationDate, 
  1863.                 modificationTime, needsUpdate, infoResult,
  1864.                 kODShellGuideStringIndexLinkSource);
  1865.     
  1866.     CATCH_ALL
  1867. //        RERAISE;
  1868.         err = ErrorCode();
  1869.     ENDTRY
  1870.  
  1871.     ODDisposeRoutineDescriptor(DrawBoxItemUPP);
  1872.     ODDisposeRoutineDescriptor(DrawKindNameUPP);
  1873.  
  1874.     refSaved = BeginUsingLibraryResources();
  1875.     ODDisposeDialog(dlg);
  1876.     EndUsingLibraryResources(refSaved);
  1877.  
  1878.     SetPort(savePort);
  1879.  
  1880.     return err;
  1881. }
  1882.                 
  1883. //------------------------------------------------------------------------------
  1884. // SetDateTimeStrings
  1885. //------------------------------------------------------------------------------
  1886.  
  1887. ODStatic void SetDateTimeStrings(
  1888.                     ODULong        dateTime,
  1889.                     Str255        dateString, 
  1890.                     Str255        timeString)
  1891. {
  1892.     if ( dateTime == 0 )
  1893.     {
  1894.         CUsingLibraryResources r;
  1895.  
  1896.         StringHandle str = GetString(kODLinkInfoStrUnknownID);
  1897.         if ( str != kODNULL )
  1898.         {
  1899.             ODLockHandle((ODHandle) str);
  1900.             ODBlockMove((ODPtr) *str, (ODPtr) dateString, (ODULong) (*str[0])+1);
  1901.             ODUnlockHandle((ODHandle) str);
  1902.             ReleaseResource((Handle) str);
  1903.         }
  1904.         else
  1905.         {
  1906.             dateString[0] = (char) 0;
  1907.         }
  1908.         timeString[0] = (char) 0;
  1909.     }
  1910.     else
  1911.     {
  1912.         DateString(dateTime, abbrevDate, dateString, kODNULL);
  1913.         TimeString(dateTime, kODFalse, timeString, kODNULL);
  1914.     }
  1915. }
  1916.  
  1917. //------------------------------------------------------------------------------
  1918. // DraftIsReadOnly
  1919. //------------------------------------------------------------------------------
  1920. ODStatic ODBoolean DraftIsReadOnly(Environment* ev, ODStorageUnit* su)
  1921. {
  1922.     return (!HAS_WRITE_ACCESS(su->GetDraft(ev)->GetPermissions(ev)));
  1923. }
  1924.  
  1925. //------------------------------------------------------------------------------
  1926. // ShowLinkDestinationInfo
  1927. //------------------------------------------------------------------------------
  1928.  
  1929. ODError ShowLinkDestinationInfoEx(
  1930.                 ODBaseLink*            link,
  1931.                 ODLinkInfo*         info,
  1932.                 ODBoolean            changesAllowed,
  1933.                 ODLinkInfoResult*    infoResult,
  1934.                 ODBoolean*            boolResult)
  1935. {
  1936.     ODError err = noErr;
  1937.     Environment* ev = somGetGlobalEnvironment();
  1938.  
  1939.     WindowPtr    savePort;                        ODVolatile(savePort);
  1940.     GetPort(&savePort);
  1941.     ODSLong        refSaved;
  1942.  
  1943.     DialogPtr      dlg = kODNULL;                    ODVolatile(dlg);
  1944.     UserItemUPP DrawBoxItemUPP = kODNULL;        ODVolatile(DrawBoxItemUPP);
  1945.     UserItemUPP DrawKindNameUPP = kODNULL;        ODVolatile(DrawKindNameUPP);
  1946.     Str255        creationDate, modificationDate;
  1947.     Str255        creationTime, modificationTime;
  1948.     ODBoolean    needsUpdate;
  1949.  
  1950.     TRY
  1951.         ODSession* session = link->GetStorageUnit(ev)->GetSession(ev);
  1952.         InitBindingNamespaceUtils(session);
  1953.         
  1954.         ODNameSpaceManager* nsm = session->GetNameSpaceManager(ev);
  1955.  
  1956.         {
  1957.             CUsingLibraryResources r;
  1958.             dlg = ODGetNewDialog(ev, kLinkDstInfoDlgID, session);
  1959.             THROW_IF_NULL(dlg);
  1960.         }
  1961.  
  1962. #ifdef _APPLEGUIDE_READY_
  1963.         DialogSetUpAppleGuide( dlg, kLinkInfoAGButton );
  1964. #endif
  1965.         SetPort(dlg);    
  1966.  
  1967.         {    CUsingLibraryResources r;
  1968.             SetDialogTextStyle(dlg, kLinkDstInfoDlgID, smCurrentScript);
  1969.         }
  1970.     
  1971.         // Vertical and horizontal lines need to be drawn
  1972.         DrawBoxItemUPP = NewUserItemProc(DrawGrayBoxItem);
  1973.         SetDialogItemHandle(dlg, kLinkInfoSeparator, (Handle) DrawBoxItemUPP);
  1974.         
  1975.         // Set up kind
  1976.         DisposeGlobalODNameAndZeroPtr(&gKindName);
  1977.         if ( info->kind && GetUserKindFromKind(nsm, info->kind, &gKindName) )
  1978.         {
  1979.             DrawKindNameUPP = NewUserItemProc(DrawKindName);
  1980.             SetAsUserItem(dlg, kLinkInfoKind, (Handle) DrawKindNameUPP);
  1981.         }
  1982.  
  1983.         // Set up creation date
  1984.         SetDateTimeStrings(info->creationTime, creationDate, creationTime);
  1985.         
  1986.         // Set up modified date
  1987.         SetDateTimeStrings(info->changeTime, modificationDate, modificationTime);
  1988.  
  1989.         // Set up Send Updates
  1990.         SetLinkUpdateUpdateControls(dlg, info->autoUpdate);
  1991.         
  1992.         needsUpdate = (info->change == kODUnknownUpdate) || (info->change != link->GetUpdateID(ev));
  1993.         
  1994.         // Disable Update Now button if updates are automatic or destination is up to date.
  1995.         if ( info->autoUpdate || !needsUpdate )
  1996.         {
  1997.             SetControlActive(dlg, kLinkInfoUpdateBtn, kODFalse);
  1998.         }
  1999.  
  2000.         // Disable some items if changes are not allowed or draft is read only
  2001.         if ( !changesAllowed || DraftIsReadOnly(ev, link->GetStorageUnit(ev)) )
  2002.         {
  2003.             SetControlActive(dlg, kLinkInfoOnSaveRadioBtn, kODFalse);
  2004.             SetControlActive(dlg, kLinkInfoManualRadioBtn, kODFalse);
  2005.             SetControlActive(dlg, kLinkInfoBreakLinkBtn, kODFalse);
  2006.             SetControlActive(dlg, kLinkInfoUpdateBtn, kODFalse);
  2007.         }
  2008.  
  2009.         *boolResult = ShowLinkInfo(dlg, creationDate, creationTime, modificationDate, 
  2010.                 modificationTime, needsUpdate, infoResult,
  2011.                 kODShellGuideStringIndexLinkDest );
  2012.  
  2013.     CATCH_ALL
  2014. //        RERAISE;
  2015.         err = ErrorCode();
  2016.     ENDTRY
  2017.  
  2018.     ODDisposeRoutineDescriptor(DrawBoxItemUPP);
  2019.     ODDisposeRoutineDescriptor(DrawKindNameUPP);
  2020.  
  2021.     refSaved = BeginUsingLibraryResources();
  2022.     ODDisposeDialog(dlg);
  2023.     EndUsingLibraryResources(refSaved);
  2024.  
  2025.     SetPort(savePort);
  2026.  
  2027.     return err;
  2028. }
  2029.  
  2030.